package com.oms.common;

import com.oms.module.admin.constant.AdminResponseCodeConstant;
import com.oms.module.merchant.constant.MerChantResponseCodeConstant;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author zhanghailong
 * @Description TODO
 * @Date 16:54 2020/3/26
 */
public class ResponseCodeConst {

    static {
        // 系统功能，从0开始，step=1000
        ResponseCodeContainer.register( ResponseCodeConst.class, 0, 1000 );
        ResponseCodeContainer.register( AdminResponseCodeConstant.class, 1001, 2000 );
        ResponseCodeContainer.register( MerChantResponseCodeConstant.class, 2001, 3000 );
    }

    /**
     * 返回成功状态码 1;
     */
    public static final int SUCC_CODE = 200;

    /**
     * 正常成功返回
     */
    public static final ResponseCodeConst SUCC = new ResponseCodeConst( SUCC_CODE, "success", true );

    /**
     * 未登录 100
     */
    public static final ResponseCodeConst LOGIN = new ResponseCodeConst( 100, "请先登录！" );

    /**
     * 参数异常 101
     */
    public static final ResponseCodeConst ERROR_PARAM = new ResponseCodeConst( 101, "参数异常！" );

    /**
     * 数据不存在 102
     */
    public static final ResponseCodeConst NOT_EXIST = new ResponseCodeConst( 102, "数据不存在" );

    /**
     * 添加失败 103
     */
    public static final ResponseCodeConst ADD_FAILED = new ResponseCodeConst( 103, "添加失败" );

    /**
     * 修改失败 104
     */
    public static ResponseCodeConst UPDATE_FAILED = new ResponseCodeConst( 104, "修改失败" );

    /**
     * 删除失败 105
     */
    public static final ResponseCodeConst DELETE_FAILED = new ResponseCodeConst( 105, "删除失败" );

    /**
     * 系统错误 106
     */
    public static final ResponseCodeConst SYS_ERROR = new ResponseCodeConst( 106, "系统错误" );

    /**
     * 数据已存在 107
     */
    public static final ResponseCodeConst AlREADY_EXIT = new ResponseCodeConst( 107, "数据已存在" );

    /**
     * 用户名重复 108
     */
    public static final ResponseCodeConst AlREADY_EXIT_LOGIN_NAME = new ResponseCodeConst( 108, "用户名重复" );

    /**
     * 导入失败 109
     */
    public static final ResponseCodeConst IMPORT_FAIL = new ResponseCodeConst( 109, "导入失败!!!" );

    /**
     * 无角色 110
     */
    public static final ResponseCodeConst NO_ROLE = new ResponseCodeConst( 110, "无角色！" );

    /**
     * 账户登录失败 111
     */
    public static final ResponseCodeConst LOFING_FAIL_ACCOUNT = new ResponseCodeConst( 111, "登录账号或密码错误" );

    /**
     * 无权限 112
     */
    public static final ResponseCodeConst NO_PSERMISSION = new ResponseCodeConst( 112, "无权限" );

    /**
     * 短信验证码错误 113
     */
    public static final ResponseCodeConst SMS_CODE_ERROR = new ResponseCodeConst( 113, "短信验证码错误" );

    /**
     * 短信验证码超时 114
     */
    public static final ResponseCodeConst SMS_CODE_EXPIRED = new ResponseCodeConst( 114, "短信验证码已过期" );

    /**
     * 需要图片验证码 115
     */
    public static final ResponseCodeConst NEED_IMG_VALIDATE_CODE = new ResponseCodeConst( 115, "需要图片验证码" );

    /**
     * 短信验证码20分钟获取5次 116
     */
    public static final ResponseCodeConst SMS_CODE_MAXIMUM = new ResponseCodeConst( 116, "获取短信验证码过于频繁，请稍后重试" );

    /**
     * 图片验证码错误 117
     */
    public static final ResponseCodeConst IMG_VALIDATE_CODE_ERROR = new ResponseCodeConst( 117, "图片验证码错误" );

    /**
     * 手机号错误 118
     */
    public static final ResponseCodeConst PHONE_ERROR = new ResponseCodeConst( 118, "手机号错误" );

    /**
     * 图片验证码超时 119
     */
    public static final ResponseCodeConst IMG_VALIDATE_CODE_EXPIRED = new ResponseCodeConst( 119, "图片验证码超时" );

    /**
     * 获取短信验证码失败 120
     */
    public static final ResponseCodeConst GET_SMS_CODE_FAIL = new ResponseCodeConst( 120, "获取短信验证码失败,请稍后再试" );

    /**
     * 状态码
     */
    protected int code;

    /**
     * 错误信息
     */
    protected String msg;

    /**
     * 是否成功
     */
    protected boolean success;

    public ResponseCodeConst() {
    }

    public ResponseCodeConst(int code, String msg) {
        super();
        this.code = code;
        this.msg = msg;
        ResponseCodeContainer.put( this );
    }

    public ResponseCodeConst(int code) {
        super();
        this.code = code;
        ResponseCodeContainer.put( this );
    }

    public ResponseCodeConst(int code, String msg, boolean success) {
        super();
        this.code = code;
        this.msg = msg;
        this.success = success;
        ResponseCodeContainer.put( this );
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    /**
     * 内部类，用于检测code范围
     */
    private static class ResponseCodeContainer {

        private static final Map<Integer, ResponseCodeConst> RESPONSE_CODE_MAP = new HashMap<>();

        private static final Map<Class<? extends ResponseCodeConst>, int[]> RESPONSE_CODE_RANGE_MAP = new HashMap<>();

        /**
         * id的范围：[start, end]左闭右闭
         *
         * @param clazz
         * @param start
         * @param end
         */
        private static void register(Class<? extends ResponseCodeConst> clazz, int start, int end) {
            if (start > end) {
                throw new IllegalArgumentException( "<ResponseDTO> start > end!" );
            }

            if (RESPONSE_CODE_RANGE_MAP.containsKey( clazz )) {
                throw new IllegalArgumentException( String.format( "<ResponseDTO> Class:%s already exist!", clazz.getSimpleName() ) );
            }
            RESPONSE_CODE_RANGE_MAP.forEach( (k, v) -> {
                if ((start >= v[0] && start <= v[1]) || (end >= v[0] && end <= v[1])) {
                    throw new IllegalArgumentException( String.format( "<ResponseDTO> Class:%s 's id range[%d,%d] has " + "intersection with " + "class:%s", clazz.getSimpleName(), start, end,
                            k.getSimpleName() ) );
                }
            } );

            RESPONSE_CODE_RANGE_MAP.put( clazz, new int[]{start, end} );

            // 提前初始化static变量，进行范围检测
            Field[] fields = clazz.getFields();
            if (fields.length != 0) {
                try {
                    fields[0].get( clazz );
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }

        public static void put(ResponseCodeConst codeConst) {
            int[] idRange = RESPONSE_CODE_RANGE_MAP.get( codeConst.getClass() );
            if (idRange == null) {
                throw new IllegalArgumentException( String.format( "<ResponseDTO> Class:%s has not been registered!", codeConst.getClass().getSimpleName() ) );
            }
            int code = codeConst.code;
            if (code < idRange[0] || code > idRange[1]) {
                throw new IllegalArgumentException( String.format( "<ResponseDTO> Id(%d) out of range[%d,%d], " + "class:%s", code, idRange[0], idRange[1], codeConst.getClass().getSimpleName() ) );
            }
            RESPONSE_CODE_MAP.put( code, codeConst );
        }
    }

}
